package name.sakanacatcher.service;

import name.sakanacatcher.entity.Com;
import name.sakanacatcher.entity.Resume;
import name.sakanacatcher.entity.Role;
import name.sakanacatcher.entity.User;
import name.sakanacatcher.repository.UserRepository;
import name.sakanacatcher.util.FileUtil;
import name.sakanacatcher.util.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class UserService implements UserDetailsService {

    @Autowired
    UserRepository userRepository;

    @Autowired
    ComService comService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    FileUtil fileUtil;

    @Autowired
    RoleService roleService;

    @Autowired
    InformService informService;

    @Autowired
    ResultUtil resultUtil;

    @Autowired
    AuthService authService;

    @Autowired
    ResumeService resumeService;

    public UserRepository getUserRepository() {
        return userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.getByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("username error");
        }
        return user;
    }

    @Transactional
    public boolean registerUser(Map<String,Object> data){
        User user = new User(
                (String) data.get("username"),
                passwordEncoder.encode((String)data.get("password"))
        );
        user.setName(user.getUsername());
        if((boolean)data.get("isCom")){
            Com defaultCom = new Com(user.getUsername() + "的公司", "公司简介","http://localhost:8090/img/1.jpg");
            Com com = comService.getComRepository().save(defaultCom);
            user.setCom(com);
            List<Role> roles = new ArrayList<>();
            roles.add(roleService.getRoleRepository().getRoleById(3));
            User newUser = userRepository.save(user);
            newUser.setRoles(roles);
            userRepository.save(user);
            return userRepository.existsById(newUser.getId());
        }
        else {
            List<Role> roles = new ArrayList<>();
            roles.add(roleService.getRoleRepository().getRoleById(5));
            User newUser = userRepository.save(user);
            newUser.setRoles(roles);
            System.out.println(newUser);
            userRepository.save(user);
            Resume resume = new Resume();
            resume.setUid(newUser.getId());
            resumeService.getResumeRepository().save(resume);
            return userRepository.existsById(newUser.getId());
        }
    }

    public User getPrincipalByCid(int cid){
        List<User> users = userRepository.getUsersByComId(cid);
        for(User user:users){
            if(authService.isCEO(user)){
                return user;
            }
        }
        return null;
    }

    public Map<String, Object> getInfoByUsername(String username){
        User user = userRepository.getByUsername(username);
        String avatar = user.getAvatar();
        List<String> rolesStr = new ArrayList<String>();
        for(Role r:user.getRoles()){
            rolesStr.add(r.getRole());
        }
        if(user.getUsername().equals("visitor")){
            avatar = "";
        }
        return Map.of("name", username, "avatar", avatar,"roles", rolesStr, "id", user.getId());
    }

    @Transactional
    public boolean updateAvatar(Map<String,Object> data){
        User user = userRepository.getById((int)data.get("id"));
        user.setAvatar((String) data.get("avatar"));
        User newUser = userRepository.save(user);
        return  newUser.getAvatar().equals((String) data.get("avatar"));
    }
    @Transactional
    public boolean addHrToCom(Map<String,Object> data) {
        User user = userRepository.getByUsername((String) data.get("username"));
        System.out.println(data);
        System.out.println(user);
        if(user.getCom() == null){
            List<Role> roles = user.getRoles();
            roles.add(roleService.getHRRole());
            user.setCom(comService.getComRepository().getById((int) data.get("cid")));
            User newUser = userRepository.save(user);
            return newUser.getCom().getId() != (int) data.get("cid") && authService.isHR(newUser);
        }
        return false;
    }
    @Transactional
    public boolean deleteHrToCom(Map<String,Object> data) {
        User user = userRepository.getByUsername((String) data.get("username"));
        if(user.getCom() == null || !authService.isHR(user)){
            return false;
        } else {
            List<Role> roles = user.getRoles();
            roles =roles.stream().filter(
                   role -> {
                       return role.getId() != roleService.getHRRole().getId();
                   }
           ).collect(Collectors.toList());
            user.setRoles(roles);
            user.setCom(null);
            User newUser = userRepository.save(user);
            return newUser.getCom() == null && !authService.isHR(newUser);
        }
    }

    @Transactional
    public boolean updateBasicInfo(Map<String,Object> data) {
        User user = getUserRepository().getByUsername((String) data.get("username"));
        user.setName((String) data.get("name"));
        User newUser = userRepository.save(user);
        return newUser.getName().equals((String) data.get("name"));
    }

    public List<User> getUsersByCid(int cid){
        return userRepository.getUsersByComId(cid);
    }

}
